import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
# 创建"char"文件夹
os.makedirs('chars', exist_ok=True)

# 读取原图
img = cv2.imread('hanzi1.jpg')
# 读取彩色图像
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 将BGR格式转换为RGB格式

# 将图像转换为灰度图像
gray_img = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2GRAY)  # 将彩色图像转换为灰度图像
# 对灰度图像进行二值化处理
binary_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV)[1]

# 创建结构元素
kernel = np.ones((3, 3), np.uint8)  # 创建一个3x3的矩形结构元素，用于开运算

# 进行腐蚀操作
eroded_img = cv2.erode(binary_img, kernel, iterations=3)

# 中值滤波去小白点
median_filtered_img = cv2.medianBlur(eroded_img, 5)

# 进行膨胀操作
dilated_img = cv2.dilate(median_filtered_img, kernel, iterations=3)

# 进行闭运算
closed_img = cv2.morphologyEx(dilated_img, cv2.MORPH_CLOSE, kernel, iterations=30)

# Canney边缘检测
img_blur = cv2.GaussianBlur(closed_img, (3, 3), 0)  # 高斯滤波
edges_with_blur = cv2.Canny(img_blur, 50, 200)

# 得到图像轮廓列表
contours, _ = cv2.findContours(edges_with_blur, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 复制图像以绘制边界框
img_copy = rgb_img.copy()
# 初始化计数器
counter = 1
# 遍历轮廓列表
for index, c in enumerate(contours):
    perimeter = cv2.arcLength(c, True)
    x, y, w, h = cv2.boundingRect(c)
    # 根据周长阈值筛选并绘制边界框
    if perimeter > 100:
        char_img = rgb_img[y:y + h, x:x + w]  # 提取汉字图像
        if counter % 2 == 0:
            char_filename = os.path.join('chars', f'char_{counter}.jpg')  # 生成文件名
            cv2.imwrite(char_filename, char_img)  # 保存汉字图像
            picture= cv2.rectangle(img_copy, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # 更新计数器
        counter += 1
# 获取chars文件夹中的所有文件名
file_list = os.listdir('chars')
# 按照文件名的数字进行排序
sorted_file_list = sorted(file_list, key=lambda x: int(x.split('_')[-1].split('.')[0]))
# 删除保存的字体文件名后为奇数的文件
for filename in file_list:
    if int(filename.split('_')[-1].split('.')[0]) % 2 == 1:
        os.remove(os.path.join('chars', filename))

# 将文件重命名为新的有序文件名
for i, filename in enumerate(sorted_file_list):
    old_path = os.path.join('chars', filename)
    new_path = os.path.join('chars', f'char_{i+1}.jpg')
    os.rename(old_path, new_path)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(20, 20))

plt.subplot(2, 4, 1)
plt.imshow(gray_img, cmap='gray')
plt.title(f"原图灰度图", size=10)

plt.subplot(2, 4, 2)
plt.imshow(binary_img, cmap='gray')
plt.title(f"全局阈值处理>>二值化图", size=10)

plt.subplot(2, 4, 3)
plt.imshow(eroded_img, cmap='gray')
plt.title(f"应用腐蚀操作>>去除噪点", size=10)

plt.subplot(2, 4, 4)
plt.imshow(dilated_img, cmap='gray')
plt.title(f"应用膨胀操作>>突出图像特征>>中值滤波去除小白点", size=10)

plt.subplot(2, 4, 5)
plt.imshow(closed_img, cmap='gray')
plt.title(f"应用闭运算>>填充闭合区域", size=10)

plt.subplot(2, 4, 6)
plt.imshow(edges_with_blur, cmap='gray')
plt.title(f"Canny边缘检测", size=10)

plt.subplot(2, 4, 7)
plt.imshow(picture)
plt.title(f"轮廓绘制>>识别结果", size=10)
# 隐藏坐标轴
for i in range(7):
    plt.xticks([]), plt.yticks([])
# 保存图像
plt.savefig('last_photo.png', dpi=500)
# 显示图像
plt.show()